#coding=utf-8
#coding=gbk
# -*- coding: encoding -*-


import os,sys,time
import re,commands

#只匹配ui进程
uiMatch = ".\."
noStatistical = [
	    'letv.remotemanager',
	    'android.process.media',
	    'com.mstar.tv.service',
	    'com.stv.net.misc',
	    'com.mstar.android.providers.tv',
    	    'com.stv.bsp.qccrashhandler'
	   ]

changedcmd =[]
commoncmd = []
dismisscmd = ['sh','dumpsys','ping','grep','logcat','<unknown>','top','busybox','chmod','ps']
focusedAc=[]
service=[]

save_file = open('meminfo.csv','w+')
process_mem_file = open('process_meminfo.csv','w+');
dir_path = "result/meminfo/"
filecount = 10
#设置 TOP N 取前面的多少个进程数据，如果取全部数据，可以把n 设置为100或者更大
m=0
n=100

'''
1,解析所有进程,加入进程列表
可以通过命令: cat meminfo.txt | sed -n '/Total PSS by process:/,/Total PSS by OOM adjustment:/'p | awk -F: '{print $2}'
2, 修改getmeminfo.sh脚本

'''
def get_file_count():
    global filecount
    cmd = " ls  -l  " + dir_path + " | grep '^-'|wc -l"
    result = commands.getoutput(cmd)
    filecount = int(result.split('.')[0])
    return filecount

#start,to分别代表要统计的开始文件和结束文件
def get_allprocess_list(start,to):
    global changedcmd, commoncmd, uiMatch

    commoncmd = get_onefile_proesslist(start) #初始化公共列表
    process_arr=commoncmd #初始化当前获取的进程列表
    for i in range(filecount)[start + 1:to]:
        #print str(i)+".txt"
        new_process_arr = get_onefile_proesslist(i)

        commoncmd = list(set(new_process_arr).intersection(set(commoncmd)))
        add_process = list(set(new_process_arr).difference(set(process_arr)))
        delete_process = list(set(process_arr).difference(set(new_process_arr)))

        changedcmd = changedcmd + add_process + delete_process
        changedcmd = list(set(changedcmd))
        process_arr = new_process_arr
        '''
        print "the added process is ++++++++++++++"
        print add_process
        print "the delete process is --------------"
        print delete_process
        print "the changed process is: "
        print changedcmd
        '''

    commoncmd = list(set(commoncmd).difference(set(dismisscmd)))
    changedcmd = list(set(changedcmd).difference(set(dismisscmd)))

    print "the changed process is :"
    print changedcmd
    print "new common process is :"
    print commoncmd


def generate_meminfo_data(file_no):

    cmd = " sed -n " + '1p'
    out=get_cmdoutput(file_no,cmd)
    save_file.write(out + '\t')
    get_Totaldata(file_no)
    parse_process_memdata(file_no)


def get_onefile_proesslist(file):
    process_list=[]

    #cmd = "cat "+file_path+" | sed -n '/Total PSS by process:/,/Total PSS by OOM adjustment:/'p | awk -F: '{print $2}'"
    cmd = " sed -n '/Total PSS by process:/,/Total PSS by OOM adjustment:/'p | awk -FkB: '{print $2}'"

    out = get_cmdoutput(file,cmd)
    cmdarr = out.split('\n')
    for cmd in cmdarr:
        if len(cmd) > 0:
            process_name = cmd.split('(pid')[0].strip()
            if len(process_name) > 0 and process_name not in dismisscmd:
		#只收集ui进程	
	        m = re.search(uiMatch,process_name)
	        if m is not None and process_name not in noStatistical:
                    process_list.append(process_name)
    return process_list

def get_cmdoutput(file,cmd):
    file_path=dir_path+str(file)+'.txt'

    full_cmd = "cat "+file_path+" | "+cmd
    out = commands.getoutput(full_cmd)
    return out

def parse_process_memdata(file):
    global commoncmd

    for process in commoncmd+changedcmd:
        cmd="sed -n '/Total PSS by process:/,/Total PSS by OOM adjustment:/'p"+"|grep "+process
        out=get_cmdoutput(file,cmd)
        #print process + ": "+out
        if(len(out.strip())>0):
            outarr=out.split('\n')
            for pr in outarr:
                process_name =pr.strip().split('kB:')[1].split('(pid')[0].strip()
                if process==process_name:
                    pss=pr.strip().split(':')[0].strip('kB').strip()
                    pss=(float(pss)+1024)/1024-1
                    #print process + " pss is: "+str(round(pss,1)) + " MB"
                    save_file.write(str(round(pss,1))+'\t')
        else:
            Pss = 0
            save_file.write(str(Pss) + '\t')

    save_file.write('\n')




def get_Totaldata(file):

    # cmd = "cat "+file_path+" | sed -n '/Total PSS by process:/,/Total PSS by OOM adjustment:/'p"
    cmd = "sed -n '/Total RAM/,/ZRAM/'p"
    out = get_cmdoutput(file, cmd)
    lines=out.split('\n')
    for line in lines:
        #print "---------------------"+line+"-------------------------"
        if line.find("Free RAM:") >-1:
            free_RAM= getram(line,"Free RAM:")
            cached_pss = get_signal_pss(line,"cached pss")
            cached_kernel=get_signal_pss(line, "cached kernel")
            free=get_signal_pss(line, "free")

            save_file.write(str(free_RAM) + '\t')
            save_file.write(str(cached_pss) + '\t')
            save_file.write(str(cached_kernel) + '\t')
            save_file.write(str(free) + '\t')

        if line.find("Used RAM:") > -1:
            used_RAM = getram(line, "Used RAM:")
            used_pss= get_signal_pss(line, "used pss")
            kernel= get_signal_pss(line, "kernel")

            save_file.write(str(used_RAM) + '\t')
            save_file.write(str(used_pss) + '\t')
            save_file.write(str(kernel) + '\t')

        if line.find("Lost RAM:") > -1:
            lost_RAM = getram(line, "Lost RAM:")

            save_file.write(str(lost_RAM) + '\t')
    #计算ui tatal pss
    uiTotal = sumUIpss(file)
    save_file.write(str(uiTotal) + '\t')

def sumUIpss(file):
    sumPss = 0;
    for process in commoncmd+changedcmd:
        cmd="sed -n '/Total PSS by process:/,/Total PSS by OOM adjustment:/'p"+"|grep "+process
        out=get_cmdoutput(file,cmd)
        #print process + " <=> "+out
        if(len(out.strip())>0):
            outarr=out.split('\n')
            for pr in outarr:
                process_name =pr.strip().split('kB:')[1].split('(pid')[0].strip()
                if process==process_name:
                    pss=pr.strip().split(':')[0].strip('kB').strip()
                    pss=(float(pss)+1024)/1024-1
                    #print process + " pss is: "+str(round(pss,1)) + " MB"
                    sumPss += round(pss,1)
    return sumPss; 

def getram(line,ram):
    linearr = line.split(':')

    valstr = linearr[1]
    pstr = '\d* kB'
    pattern = re.compile(r'' + pstr)
    match = pattern.search(valstr)
    if match:
        ram = (float(match.group().split(' kB')[0]) + 1024) / 1024 - 1
    return round(ram,1)

def get_signal_pss(line,pss_name):
    linearr = line.split(':')

    valstr = linearr[1]
    pstr = '\d+ '+pss_name
    pattern = re.compile(r'' + pstr)
    match = pattern.search(valstr)
    if match:
        pss = (float(match.group().split(' ')[0]) + 1024) / 1024 - 1
    return round(pss,1)


def get_statistic_mem(process_service_name):
    foremem=[]
    backmem=[]

    for i in range(filecount + 1)[1:]:
        print str(i)+".txt start"
        cmd = " sed -n " + '1p'
        out = get_cmdoutput(i, cmd)
        focusedac = out.split('\t')[1].split('/')[0].strip()
        cmd = "sed -n '/Total PSS by process:/,/Total PSS by OOM adjustment:/'p" + "|grep " + process_service_name
        out = get_cmdoutput(i, cmd)
        #print process_service_name + " search result is : "+out
        if (len(out.strip()) > 0):
            outarr = out.split('\n')
            for pr in outarr:
                process_name = pr.strip().split('kB:')[1].split('(pid')[0].strip()
                if process_name==process_service_name:
                    pss_str = pr.strip().split(':')[0].strip('kB').strip()
                    pss = (float(pss_str) + 1024) / 1024 - 1
                    if process_service_name == focusedac:
                        if (len(pss_str) > 0):
                            foremem.append(round(pss,1))
                        else:
                            foremem.append(0)
                    else:

                        if (len(pss_str) > 0):
                            backmem.append(round(pss,1))
                        elif len(backmem) > 0:

                            backmem.append(0)

    print process_service_name+" 前台内存数据为: "+str(foremem)
    print process_service_name+" 后台内存数据为:"+str(backmem)
    if(len(foremem)==0):
        process_mem_file.write(process_service_name + '\t' + '0' + '\t' + '0' + '\t' + str(
            max(backmem)) + '\t' + str(min(backmem)) +'\t'+str(backmem[0:6])+ '\n')

    elif(len(backmem)==0):
        process_mem_file.write(process_service_name + '\t' + str(max(foremem)) + '\t' + str(min(foremem)) + '\t' + '0' + '\t' + '0' +'\t'+str(backmem[0:6])+ '\n')

    else:
        process_mem_file.write(process_service_name+'\t'+str(max(foremem))+'\t'+str(min(foremem))+'\t'+str(max(backmem))+'\t'+str(min(backmem))+'\t'+str(backmem[0:6])+'\n')





def init_table2(): #方便过滤数据
    save_file.write("time\t")
    save_file.write("FocusedActivity\t")
    save_file.write("Free RAM\tcached pss\tcached kernel\tfree\tUsed RAM\tused pss\tused kernel\tLost RAM\tEui RAM\t")

    for process in commoncmd:
        save_file.write(process + "\t")

    for process in changedcmd:
        if process == changedcmd[-1]:
            save_file.write(process)
        else:
            # save_file.write(process + "\t\t\t\t") #显示全部参数,包括Vss和Rss
            save_file.write(process + "\t")
    save_file.write('\n')

def init_basicdata():
    global filecount

    filecount = get_file_count()
    print filecount
    get_allprocess_list(1, filecount)

def gernerate_allmem_file():
    tt1 = time.strftime("%H:%M:%S", time.localtime())
    init_table2()

    for i in range(filecount + 1)[1:]:
        print str(i)+'.txt start'
        generate_meminfo_data(i)
    save_file.close()
    tt2 = time.strftime("%H:%M:%S", time.localtime())
    print tt1
    print tt2

def gernerate_statisticMem_file():
    tt1 = time.strftime("%H:%M:%S", time.localtime())
    cmdlist = changedcmd + commoncmd
    process_mem_file.write("应用/服务名称\t 前台最大值 \t 前台最小值 \t 后台最大值\t 后台最小值 \t后台1分钟内存 \n")
    for acs in cmdlist:
        print acs
        get_statistic_mem(acs)

    process_mem_file.close()
    tt2 = time.strftime("%H:%M:%S", time.localtime())
    print tt1
    print tt2


if __name__ == '__main__':
    init_basicdata()
    gernerate_allmem_file()
    #gernerate_statisticMem_file()
